import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './common/filters/allExceptions.filter';
import { TransformInterceptor } from './common/interceptor/transform.interceptor';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import {
  BadRequestException,
  ValidationError,
  ValidationPipe,
} from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 全局注册异常过滤器
  app.useGlobalFilters(new AllExceptionsFilter());
  // 全局注册拦截器
  app.useGlobalInterceptors(new TransformInterceptor());
  // 全局注册管道
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true, // 开启自动类型转换
      transformOptions: {
        enableImplicitConversion: true, // 开启隐式类型转换
      },
      exceptionFactory: (errors: ValidationError[]) => {
        const result = errors.map((error) => {
          // 递归获取嵌套验证错误
          const getNestedErrors = (err: ValidationError): any => {
            if (err.children && err.children.length > 0) {
              return {
                field: err.property,
                constraints: err.constraints
                  ? Object.values(err.constraints)
                  : [],
                children: err.children.map(getNestedErrors),
              };
            }
            return {
              field: err.property,
              constraints: err.constraints
                ? Object.values(err.constraints)
                : [],
              value: err.value, // 显示提交的值
            };
          };

          return getNestedErrors(error);
        });
        return new BadRequestException({
          message: '请求参数验证失败',
          errors: result,
        });
      },
    }),
  );

  const config = new DocumentBuilder()
    .setTitle('video-demo API文档')
    .setDescription('这是一个普普通通的API文档')
    .setVersion('1.0')
    .build();
  const documentFactory = () => SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api-docs', app, documentFactory);

  await app.listen(3000);
}
bootstrap();
